#include "device/Bus.h"

bool Bus::read(word_t start_addr, size_t length, uint8_t* buffer, bool& mmio)
{
    auto it = devices.upper_bound(std::make_pair(start_addr, UINT32_MAX));
    if (it == devices.begin()) return false;
    it = std::prev(it);
    uint64_t end_addr = start_addr + length;
    if (it->first.first <= start_addr && end_addr <= it->first.second) {
        // uint64_t dev_size = it->first.second - it->first.first;
        return it->second->read(start_addr, length, buffer, mmio);
    }
    return false;
}

bool Bus::write(word_t start_addr, size_t length, const uint8_t* buffer, bool& mmio)
{
    auto it = devices.upper_bound(std::make_pair(start_addr, UINT32_MAX));
    if (it == devices.begin()) return false;
    it = std::prev(it);
    uint64_t end_addr = start_addr + length;
    if (it->first.first <= start_addr && end_addr <= it->first.second) {
        // uint64_t dev_size = it->first.second - it->first.first;
        return it->second->write(start_addr, length, buffer, mmio);
    }
    return false;
}

void Bus::update()
{
    for (auto& [_, device] : devices) {
        device->update();
    }
}

void Bus::add_device(word_t start_addr, size_t size, Device* device)
{
    devices[std::make_pair(start_addr, start_addr + size)] = device;
}
